use rusqlite::{params, Connection, Result};

use crate::{common, domain::App};

/// 添加应用
///
/// 根据应用id、名称、URL添加应用
///
/// # 参数列表
/// * `conn`        数据库连接
/// * `name`        应用名称       String
/// * `url`         应用URL       String
/// * `icon`        应用图标       String
/// * `description` 应用描述       String
///
/// # 返回结果
/// * `Result<String, String>`   添加成功则返回Ok(应用id), 添加失败则返回Err(String)
pub fn add_app(conn: &Connection, name: &str, url: &str, icon: &str, description: &str) -> Result<String, String> {
    // 生成 ID
    let id = common::snowflake_id();
    conn.execute(
        "INSERT INTO apps (id, name, url, icon, description) VALUES (?1, ?2, ?3, ?4, ?5)",
        params![id, name, url, icon, description]
    ).map_err(|e| format!("插入数据失败: {}", e))?;
    Ok(id)
}

/// 获取应用列表
///
/// 获取应用列表
/// # 返回结果
/// * `Result<Vec<App>, String>`   获取成功则返回Ok(`Vec<App>`), 获取失败则返回Err(String)
pub fn get_apps(conn: &Connection) -> Result<Vec<App>, String> {
    let mut stmt = conn.prepare("SELECT id, name, url, icon, description FROM apps")
        .map_err(|e| format!("准备查询失败: {}", e))?;

    let apps_iter = stmt.query_map([], |row| {
        Ok(App {
            id: row.get("id")?,
            name: row.get("name")?,
            url: row.get("url")?,
            icon: row.get("icon")?,
            description: row.get("description")?,
        })
    })
        .map_err(|e| format!("执行查询失败: {}", e))?;

    apps_iter.collect::<Result<Vec<_>, _>>()
        .map_err(|e| format!("数据解析失败: {}", e))
}

/// 获取应用
///
/// 根据应用id获取应用
///
/// # 参数列表
/// * `conn`    数据库连接
/// * `id`      应用id        String
///
/// # 返回结果
/// * `Result<App, String>`   成功则返回Ok(App), 失败则返回Err(String)
pub fn get_app(conn: &Connection, id: &str) -> Result<App, String> {
    let mut stmt = conn.prepare("SELECT id, name, url, icon, description FROM apps WHERE id = ?")
        .map_err(|e| format!("准备查询失败: {}", e))?;
    let app = stmt.query_row(params![id], |row| {
        Ok(App {
            id: row.get("id")?,
            name: row.get("name")?,
            url: row.get("url")?,
            icon: row.get("icon")?,
            description: row.get("description")?,
        })
    })
        .map_err(|e| format!("执行查询失败: {}", e))?;
    Ok(app)
}

/// 编辑应用
///
/// 根据应用id编辑应用名称和URL
///
/// # 参数列表
/// * `conn`        数据库连接
/// * `id`          应用id        String
/// * `name`        应用名称       String
/// * `url`         应用URL       String
/// * `icon`        应用图标       String
/// * `description` 应用描述       String
///
/// # 返回结果
/// * `Result<(), String>`   编辑成功则返回Ok(()), 编辑失败则返回Err(String)
pub fn edit_app(conn: &Connection, id: &str, name: &str, url: &str, icon: &str, description: &str) -> Result<App, String> {
    conn.execute(
        "UPDATE apps SET name = ?1, url = ?2, icon = ?3, description = ?4 WHERE id = ?5",
        params![name, url, icon, description, id]
    ).map_err(|e| format!("编辑数据失败: {}", e))?;
    Ok(App {
        id: id.to_string(),
        name: name.to_string(),
        url: url.to_string(),
        icon: icon.to_string(),
        description: description.to_string(),
    })
}

/// 删除应用
///
/// 根据应用id删除应用
///
/// # 参数列表
/// * `conn`    数据库连接
/// * `id`      应用id        String
///
/// # 返回结果
/// * `Result<(), String>`   成功则返回Ok(()), 失败则返回Err(String)
pub fn delete_app(conn: &Connection, id: &str) -> Result<(), String> {
    conn.execute("DELETE FROM apps WHERE id = ?1", params![id])
        .map_err(|e| format!("删除数据失败: {}", e))?;
    Ok(())
}